package com.cencat.merchant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cencat.common.enums.AuditStatus;
import com.cencat.common.enums.ErrorCode;
import com.cencat.common.exception.BusinessException;
import com.cencat.common.utils.CencatStringUtils;
import com.cencat.merchant.dto.MerchantAuditDTO;
import com.cencat.merchant.entity.Merchant;
import com.cencat.common.enums.MerchantStatus;
import com.cencat.merchant.mapper.MerchantMapper;
import com.cencat.merchant.service.MerchantAuditService;
import com.cencat.merchant.vo.MerchantAuditHistoryVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商家审核服务实现类
 * 
 * @author cencat
 * @since 2024-01-01
 */
@Service
@Slf4j
public class MerchantAuditServiceImpl implements MerchantAuditService {

    @Autowired
    private MerchantMapper merchantMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean submitAudit(Long merchantId, MerchantAuditDTO auditDTO) throws BusinessException {
        log.info("开始提交商家审核: merchantId={}", merchantId);
        
        try {
            // 参数校验
            if (merchantId == null || auditDTO == null) {
                throw new BusinessException(ErrorCode.PARAM_ERROR);
            }
            
            // 查询商家信息
            Merchant merchant = merchantMapper.selectById(merchantId);
            if (merchant == null) {
                throw new BusinessException(ErrorCode.MERCHANT_NOT_EXISTS);
            }
            
            // 检查商家状态是否可以提交审核
            if (!canSubmitAudit(merchant.getStatus())) {
                throw new BusinessException(ErrorCode.OPERATION_FAILED, "当前商家状态不允许提交审核");
            }
            
            // 更新商家状态为待审核
            merchant.setStatus(MerchantStatus.PENDING.getCode());
            
            // 更新商家审核状态
            merchant.setAuditStatus(AuditStatus.PENDING.name());
            merchant.setAuditRemark(auditDTO.getAuditRemark());
            merchant.setUpdateTime(LocalDateTime.now());
            
            int result = merchantMapper.updateById(merchant);
            if (result <= 0) {
                throw new BusinessException(ErrorCode.OPERATION_FAILED);
            }
            
            log.info("商家审核提交成功: merchantId={}", merchantId);
            return true;
            
        } catch (BusinessException e) {
            log.error("提交商家审核失败: merchantId={}, error={}", merchantId, e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("提交商家审核异常: merchantId={}, error={}", merchantId, e.getMessage(), e);
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean auditMerchant(Long merchantId, AuditStatus auditStatus, String auditRemark, Long auditorId) throws BusinessException {
        log.info("开始审核商家: merchantId={}, auditStatus={}, auditorId={}", merchantId, auditStatus, auditorId);
        
        try {
            // 参数校验
            if (merchantId == null || auditStatus == null || auditorId == null) {
                throw new BusinessException(ErrorCode.PARAM_ERROR);
            }
            
            // 查询商家信息
            Merchant merchant = merchantMapper.selectById(merchantId);
            if (merchant == null) {
                throw new BusinessException(ErrorCode.MERCHANT_NOT_EXISTS);
            }
            
            // 检查是否可以审核
            if (!canAudit(merchantId, auditorId)) {
                throw new BusinessException(ErrorCode.OPERATION_FAILED, "无权限审核该商家");
            }
            
            // 更新审核信息
            merchant.setAuditStatus(auditStatus.name());
            merchant.setAuditRemark(auditRemark);
            merchant.setAuditTime(LocalDateTime.now());
            merchant.setAuditorId(auditorId);
            merchant.setUpdateTime(LocalDateTime.now());
            
            // 根据审核结果更新商家状态
            if (auditStatus == AuditStatus.APPROVED) {
                merchant.setStatus(MerchantStatus.ACTIVE.getCode());
            } else if (auditStatus == AuditStatus.REJECTED) {
                merchant.setStatus(MerchantStatus.REJECTED.getCode());
            }
            
            int result = merchantMapper.updateById(merchant);
            if (result <= 0) {
                throw new BusinessException(ErrorCode.OPERATION_FAILED);
            }
            
            // 发送审核通知
            sendAuditNotification(merchantId, auditStatus, auditRemark);
            
            log.info("商家审核完成: merchantId={}, auditStatus={}", merchantId, auditStatus);
            return true;
            
        } catch (BusinessException e) {
            log.error("审核商家失败: merchantId={}, error={}", merchantId, e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("审核商家异常: merchantId={}, error={}", merchantId, e.getMessage(), e);
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchAuditMerchants(List<Long> merchantIds, AuditStatus auditStatus, String auditRemark, Long auditorId) throws BusinessException {
        log.info("开始批量审核商家: merchantIds={}, auditStatus={}, auditorId={}", merchantIds, auditStatus, auditorId);
        
        try {
            // 参数校验
            if (merchantIds == null || merchantIds.isEmpty() || auditStatus == null || auditorId == null) {
                throw new BusinessException(ErrorCode.PARAM_ERROR);
            }
            
            // 批量审核
            for (Long merchantId : merchantIds) {
                try {
                    auditMerchant(merchantId, auditStatus, auditRemark, auditorId);
                } catch (Exception e) {
                    log.error("批量审核中单个商家审核失败: merchantId={}, error={}", merchantId, e.getMessage());
                    // 继续处理其他商家，不中断整个批量操作
                }
            }
            
            log.info("批量审核商家完成: merchantIds={}", merchantIds);
            return true;
            
        } catch (Exception e) {
            log.error("批量审核商家异常: merchantIds={}, error={}", merchantIds, e.getMessage(), e);
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean withdrawAudit(Long merchantId, String reason) throws BusinessException {
        log.info("开始撤回审核: merchantId={}, reason={}", merchantId, reason);
        
        try {
            // 参数校验
            if (merchantId == null) {
                throw new BusinessException(ErrorCode.PARAM_ERROR);
            }
            
            // 查询商家信息
            Merchant merchant = merchantMapper.selectById(merchantId);
            if (merchant == null) {
                throw new BusinessException(ErrorCode.MERCHANT_NOT_EXISTS);
            }
            
            // 检查是否可以撤回
            if (!AuditStatus.PENDING.name().equals(merchant.getAuditStatus())) {
                throw new BusinessException(ErrorCode.OPERATION_FAILED, "只有待审核状态的商家才能撤回审核");
            }
            
            // 撤回审核
            merchant.setAuditStatus(AuditStatus.WITHDRAWN.name());
            merchant.setAuditRemark(reason);
            merchant.setUpdateTime(LocalDateTime.now());
            
            int result = merchantMapper.updateById(merchant);
            if (result <= 0) {
                throw new BusinessException(ErrorCode.OPERATION_FAILED);
            }
            
            log.info("撤回审核成功: merchantId={}", merchantId);
            return true;
            
        } catch (BusinessException e) {
            log.error("撤回审核失败: merchantId={}, error={}", merchantId, e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("撤回审核异常: merchantId={}, error={}", merchantId, e.getMessage(), e);
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
    }

    @Override
    public List<MerchantAuditHistoryVO> getAuditHistory(Long merchantId) {
        log.info("获取审核历史: merchantId={}", merchantId);
        
        try {
            // 参数校验
            if (merchantId == null) {
                return new ArrayList<>();
            }
            
            // 查询审核历史（这里简化处理，实际应该有专门的审核历史表）
            Merchant merchant = merchantMapper.selectById(merchantId);
            if (merchant == null) {
                return new ArrayList<>();
            }
            
            // 构造审核历史VO
            MerchantAuditHistoryVO historyVO = new MerchantAuditHistoryVO();
            historyVO.setId(merchant.getId());
            historyVO.setMerchantId(merchantId);
            historyVO.setMerchantName(merchant.getMerchantName());
            historyVO.setAuditStatus(AuditStatus.getByCode(merchant.getAuditStatus()));
            historyVO.setAuditRemark(merchant.getAuditRemark());
            historyVO.setAuditTime(merchant.getAuditTime());
            historyVO.setAuditorId(merchant.getAuditorId());
            historyVO.setCreateTime(merchant.getCreateTime());
            historyVO.setUpdateTime(merchant.getUpdateTime());
            
            return Arrays.asList(historyVO);
            
        } catch (Exception e) {
            log.error("获取审核历史异常: merchantId={}, error={}", merchantId, e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<Long> getPendingAuditMerchants(Long tenantId, Long auditorId) {
        log.info("获取待审核商家列表: tenantId={}, auditorId={}", tenantId, auditorId);
        
        try {
            LambdaQueryWrapper<Merchant> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Merchant::getAuditStatus, AuditStatus.PENDING.name());
            
            if (tenantId != null) {
                queryWrapper.eq(Merchant::getTenantId, tenantId);
            }
            
            List<Merchant> merchants = merchantMapper.selectList(queryWrapper);
            return merchants.stream().map(Merchant::getId).collect(Collectors.toList());
            
        } catch (Exception e) {
            log.error("获取待审核商家列表异常: tenantId={}, error={}", tenantId, e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    @Override
    public Boolean canAudit(Long merchantId, Long auditorId) {
        // 简化处理，实际应该根据权限系统判断
        return merchantId != null && auditorId != null;
    }

    @Override
    public Object getAuditStatistics(Long tenantId, String startDate, String endDate) {
        log.info("获取审核统计信息: tenantId={}, startDate={}, endDate={}", tenantId, startDate, endDate);
        
        try {
            Map<String, Object> statistics = new HashMap<>();
            
            LambdaQueryWrapper<Merchant> queryWrapper = new LambdaQueryWrapper<>();
            if (tenantId != null) {
                queryWrapper.eq(Merchant::getTenantId, tenantId);
            }
            
            // 统计各状态的商家数量
            long pendingCount = merchantMapper.selectCount(
                queryWrapper.clone().eq(Merchant::getAuditStatus, AuditStatus.PENDING.name())
            );
            long approvedCount = merchantMapper.selectCount(
                queryWrapper.clone().eq(Merchant::getAuditStatus, AuditStatus.APPROVED.name())
            );
            long rejectedCount = merchantMapper.selectCount(
                queryWrapper.clone().eq(Merchant::getAuditStatus, AuditStatus.REJECTED.name())
            );
            
            statistics.put("pendingCount", pendingCount);
            statistics.put("approvedCount", approvedCount);
            statistics.put("rejectedCount", rejectedCount);
            statistics.put("totalCount", pendingCount + approvedCount + rejectedCount);
            
            return statistics;
            
        } catch (Exception e) {
            log.error("获取审核统计信息异常: tenantId={}, error={}", tenantId, e.getMessage(), e);
            return new HashMap<>();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean autoAudit(Long merchantId) throws BusinessException {
        log.info("开始自动审核: merchantId={}", merchantId);
        
        try {
            // 参数校验
            if (merchantId == null) {
                throw new BusinessException(ErrorCode.PARAM_ERROR);
            }
            
            // 查询商家信息
            Merchant merchant = merchantMapper.selectById(merchantId);
            if (merchant == null) {
                throw new BusinessException(ErrorCode.MERCHANT_NOT_EXISTS);
            }
            
            // 自动审核逻辑（简化处理）
            boolean autoApproved = checkAutoAuditConditions(merchant);
            
            AuditStatus auditStatus = autoApproved ? AuditStatus.APPROVED : AuditStatus.REJECTED;
            String auditRemark = autoApproved ? "系统自动审核通过" : "系统自动审核拒绝";
            
            // 执行审核
            return auditMerchant(merchantId, auditStatus, auditRemark, 0L); // 0L表示系统自动审核
            
        } catch (BusinessException e) {
            log.error("自动审核失败: merchantId={}, error={}", merchantId, e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("自动审核异常: merchantId={}, error={}", merchantId, e.getMessage(), e);
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
    }

    @Override
    public Boolean sendAuditNotification(Long merchantId, AuditStatus auditStatus, String auditRemark) {
        log.info("发送审核通知: merchantId={}, auditStatus={}", merchantId, auditStatus);
        
        try {
            // 这里应该集成消息通知服务，发送短信、邮件或站内信
            // 简化处理，只记录日志
            log.info("审核通知已发送: merchantId={}, auditStatus={}, remark={}", merchantId, auditStatus, auditRemark);
            return true;
            
        } catch (Exception e) {
            log.error("发送审核通知异常: merchantId={}, error={}", merchantId, e.getMessage(), e);
            return false;
        }
    }

    /**
     * 检查商家状态是否可以提交审核
     */
    private boolean canSubmitAudit(Integer status) {
        return MerchantStatus.INACTIVE.getCode().equals(status) || 
               MerchantStatus.REJECTED.getCode().equals(status);
    }

    /**
     * 检查自动审核条件
     */
    private boolean checkAutoAuditConditions(Merchant merchant) {
        // 简化的自动审核条件
        return CencatStringUtils.isNotBlank(merchant.getMerchantName()) &&
               CencatStringUtils.isNotBlank(merchant.getContactPhone()) &&
               CencatStringUtils.isNotBlank(merchant.getBusinessLicense());
    }
}